home *** CD-ROM | disk | FTP | other *** search
- /*{{{}}}*/
- /*{{{ #includes*/
- #include <ctype.h>
- #include <string.h>
- #include <stdlib.h>
- #include <stdio.h>
-
- #define OPTMAC_C
-
- #include "keybind.h"
- /*}}} */
-
- #ifndef NO_OPTI
- /*{{{ next_command*/
- # include <h/codelg.h>
-
- private TOKEN *next_command(TOKEN *x)
- { if (*x>O_EXE_MACRO || *x<O_NOP) return(x+1);
- switch (cmd_type[*x-O_NOP])
- { case COM_II:
- x++;
- case COM_I:
- case COM_C:
- case COM_A:
- return(x+2);
- case COM_IIP:
- x++;
- case COM_IP:
- x++;
- case COM_P:
- x++;
- while (*x!=M_END_MACRO)
- if (*x==M_INT_STRING) x+=2; else x++;
- case COM:
- return(x+1);
- default:
- fprintf(stderr,"CRASH\n");
- kbd_exit(1);
- }
-
- return(0);
- }
- /*}}} */
- /*{{{ jmp_dest*/
- private TOKEN *jmp_dest(TOKEN *x)
- {
- switch(*x)
- { CASES_M_CALL
- return(x+1+*x-M_CALL_0);
- CASES_M_JMP
- return(x+1+*x-M_JMP_0);
- CASES_M_JMP_FALSE
- return(x+1+*x-M_JMP_FALSE_0);
- CASES_M_JMP_TRUE
- return(x+1+*x-M_JMP_TRUE_0);
- case M_CALL:
- case M_JMP:
- case M_JMP_FALSE:
- case M_JMP_TRUE:
- return(x+2+*(x+1));
- default:
- break;
- }
- kbd_exit(1);
- }
- /*}}} */
- /*{{{ optmac*/
- /*{{{ jumped_on, uses jmp-information, stored in buff*/
- /*{{{ jumped_on_loop*/
- private boolean jumped_on_loop(TOKEN *from,TOKEN *to,TOKEN *start,TOKEN *buff)
- {
- to=buff+(to-start);
- from=buff+(from-start);
- while (from<to)
- if (*from++)
- return(True);
- return(False);
- }
- /*}}} */
- # define jumped_on(from,to) jumped_on_loop(from,to,start,buff)
- /*}}} */
-
- # define STR_CUT_LG 2
- public TOKEN *opt_mac
- ( TOKEN *start,
- TOKEN *end,
- boolean no_not_opt,
- boolean rc_string_gen,
- boolean fix_args
- )
- {
- /*{{{ variables*/
- boolean changed;
- int loop,loop_max,s_jmp_cut,s_modified,s_shrink;
- TOKEN buff[OCL_CODE_LEN];
- enum
- { pre_cut,
- cut_strings,
- set_no_test,
- set_fixed_cmd,
- opt_ready
- } opt_type;
- /*}}} */
-
- loop=0;
- loop_max=4*(end-start);
- s_jmp_cut=s_shrink=s_modified=0;
- opt_type=fix_args?set_fixed_cmd:pre_cut;
- do
- /*{{{ one optimisation step*/
- { int jmp_cut,modified,shrink;
-
- changed=False;
- jmp_cut=shrink=modified=0;
- /*{{{ start->buff, jmp opt*/
- { TOKEN *current,*dest,*next,*jmp;
-
- for (current=start,dest=buff;current!=end;)
- { boolean inverse=False;
-
- next=next_command(current);
- switch (*current)
- { case M_CALL:
- case M_JMP:
- /*{{{ cut simple jmp-sequences*/
- { TOKEN typ= *current;
- int loop_max;
-
- for
- ( loop_max=end-start,jmp=jmp_dest(current) ; jmp!=end ; )
- { switch (*jmp)
- { case O_NOP:
- jmp++;changed=True;jmp_cut++;continue;
- case M_JMP:
- if (loop_max--<0) break;
- jmp=jmp_dest(jmp);
- changed=True;
- jmp_cut++;
- continue;
- case M_NOT:
- if (no_not_opt) break;
- fprintf(stderr,"JMP-NOT optimizer crash\n");
- no_not_opt=True;
- next=start;
- dest=buff;
- continue;
- default:
- break;
- }
- break;
- }
- dest=generate_jmp(typ,dest,buff+(jmp-start));
- current=next;
- continue;
- }
- /*}}} */
- case M_NOT:
- /*{{{ break, or prefix for jmp-condition*/
- if (no_not_opt)
- { *dest++ = *current++;continue; }
- else
- { do
- /*{{{ skip one NOT*/
- { inverse= !inverse;
- changed=True;
- jmp_cut++;
- *dest++ = O_NOP;
- current=next;
- next=next_command(current);
- }
- /*}}} */
- while (*current==M_NOT && next!=end);
- if (current!=end && *current!=M_JMP_FALSE && *current!=M_JMP_TRUE)
- /*{{{ cannot optimize NOT's, this must be a tricky code!*/
- { fprintf(stderr,"JMP-NOT optimizer crash\n");
- no_not_opt=True;
- current=start;
- dest=buff;
- continue;
- }
- /*}}} */
- }
- /*}}} */
- case M_JMP_TRUE:
- case M_JMP_FALSE:
- /*{{{ handle jmp-sequences, value of tag is known*/
- { TOKEN typ;
- int loop_max;
- boolean tag_value;
-
- tag_value= *current==M_JMP_TRUE;
- typ=tag_value?(inverse?M_JMP_FALSE:M_JMP_TRUE)
- :(inverse?M_JMP_TRUE:M_JMP_FALSE);
- for
- ( loop_max=end-start,jmp=jmp_dest(current) ; jmp!=end ; )
- { switch (*jmp)
- { case O_NOP:
- jmp++;changed=True;jmp_cut++;continue;
- case M_JMP:
- if (loop_max--<0) break;
- jmp=jmp_dest(jmp);
- changed=True;
- jmp_cut++;
- loop_max--;
- continue;
- case M_NOT:
- if (no_not_opt) break;
- tag_value = !tag_value;
- jmp+=1;
- jmp_cut++;
- changed=True;
- continue;
- case M_JMP_FALSE:
- if (loop_max--<0) break;
- if (tag_value) jmp+=2; else jmp=jmp_dest(jmp);
- changed=True;
- jmp_cut++;
- continue;
- case M_JMP_TRUE:
- if (loop_max--<0) break;
- if (tag_value) jmp=jmp_dest(jmp); else jmp+=2;
- changed=True;
- jmp_cut++;
- continue;
- default:
- break;
- }
- break;
- }
- dest=generate_jmp(typ,dest,buff+(jmp-start));
- current=next;
- continue;
- }
- /*}}} */
- default:
- /*{{{ copy the code*/
- for (;current!=next;*dest++ = *current++);
- continue;
- /*}}} */
- }
- }
- }
- /*}}} */
- /*{{{ buff->start, shrink and modify to better code*/
- { TOKEN *current,*next,*dest;
-
- /*{{{ mark reachable commands*/
- for (current=start;current!=end;*current++ = O_NOP);
- for (dest=end,start[0]=0;;)
- {
- if (dest==end)
- /*{{{ look for next reached, unhandled command*/
- {
- for (dest=start;dest!=end;) if (*dest==0) break; else dest++;
- if (dest==end) break;
- current=buff+(dest-start);
- continue;
- }
- /*}}} */
- else if (*dest!=M_END_MACRO)
- /*{{{ handle a reachable, unhandled command*/
- { *dest=M_END_MACRO;
- switch (*current)
- { case O_NOP:
- *dest=O_NOP;
- current++;
- dest++;
- continue;
- CASES_M_CALL case M_CALL:
- CASES_M_JMP case M_JMP:
- CASES_M_JMP_FALSE case M_JMP_FALSE:
- CASES_M_JMP_TRUE case M_JMP_TRUE:
- /*{{{ mark jmp-dest*/
- { TOKEN *jmp;
-
- jmp=start+(jmp_dest(current)-buff);
- if (jmp!=end && *jmp==O_NOP && jmp!=dest)
- *jmp=0;
- }
- /*}}} */
- default:
- { boolean no_cont;
-
- /*{{{ set no_cont to correct value, maybe set opt_end!*/
- switch (*current)
- { case M_EXIT:
- case M_END_MACRO:
- CASES_M_JMP
- case M_JMP:
- no_cont=True;
- break;
- default:
- no_cont=False;
- }
- /*}}} */
- next=next_command(current);
- for (;current!=next;current++,*dest++=M_END_MACRO);
- if (no_cont)
- dest=end;
- continue;
- }
- }
- }
- /*}}} */
- else
- {
- dest=end;
- }
- }
- /*}}} */
- /*{{{ shrink code*/
- { boolean shrinking;
-
- shrinking=False;
- /*{{{ get new adresses*/
- { int i;
-
- for (current=start,i=0;current!=end;current++)
- *current=((*current==M_END_MACRO)?i++:(shrinking=True,-1));
- *end=i;
- }
- /*}}} */
- if (shrinking)
- /*{{{ change jmps*/
- for
- ( current=start
- ; current!=end
- ; current=start+(next_command(buff+(current-start))-buff)
- )
- { TOKEN *x;
-
- if (*current!=-1)
- { switch(*(x=buff+(current-start)))
- { case M_CALL:
- case M_JMP:
- case M_JMP_FALSE:
- case M_JMP_TRUE:
- *(x+1)= start[jmp_dest(x)-buff]-(*current+2);
- break;
- CASES_M_CALL
- *x=M_CALL_0+start[jmp_dest(x)-buff]-(*current+1);
- break;
- CASES_M_JMP
- *x=M_JMP_0+start[jmp_dest(x)-buff]-(*current+1);
- break;
- CASES_M_JMP_FALSE
- *x=M_JMP_FALSE_0+start[jmp_dest(x)-buff]-(*current+1);
- break;
- CASES_M_JMP_TRUE
- *x=M_JMP_TRUE_0+start[jmp_dest(x)-buff]-(*current+1);
- break;
- default:
- break;
- }
- }
- }
- /*}}} */
- }
- /*{{{ copy and shrink, clear buff*/
- for (current=start,dest=buff;current+shrink!=end;*dest++=0)
- if (current[shrink]!=-1)
- *current++= *dest;
- else
- shrink++;
- end-=shrink;
- /*}}} */
- /*}}} */
- /*{{{ all jmp's to M_END_MACRO to opt_end!, get jmp-on information*/
- for (current=start;current!=end;)
- switch (*current)
- { CASES_M_CALL
- CASES_M_JMP
- CASES_M_JMP_FALSE
- CASES_M_JMP_TRUE
- next=jmp_dest(current);
- buff[next-start]=1;
- current++;
- continue;
- case M_CALL:
- case M_JMP:
- case M_JMP_FALSE:
- case M_JMP_TRUE:
- next=jmp_dest(current);
- buff[next-start]=1;
- current+=2;
- continue;
- default:
- current=next_command(current);
- continue;
- }
- /*}}} */
- /*{{{ modify some OCL-assembler patterns*/
- for (current=start;current!=end;)
- { TOKEN cur_token;
-
- cur_token = *current;
- next=next_command(current);
- switch (opt_type)
- {
- case set_no_test:
- /*{{{ no explicit test after some commands*/
- switch (cur_token)
- { default:
- goto skip_code;
- case M_ADD_COUNTER:
- case M_SUM_COUNTER:
- case M_INV_COUNTER:
- if
- ( next!=end
- && next[0]==M_NULL_COUNTER
- && current[1]==next[1]
- && !jumped_on(next,next+2)
- )
- { current=next;
- *current++=O_NOP;
- *current++=O_NOP;
- goto modif_code;
- }
- goto skip_code;
- }
- /*}}} */
- case set_fixed_cmd:
- /*{{{ gen fixed argument commands*/
- switch(cur_token)
- { case M_ADD_COUNTER:
- case M_SET_COUNTER:
- if
- /*{{{ adding argument in fixed range*/
- ( current[2]<=FIXED_COMMAND_RANGE
- && current[2]>=-FIXED_COMMAND_RANGE
- )
- /*}}} */
- /*{{{ fixed argument version*/
- { current[0]+=RANGE_ADD+current[2];
- current[2]=O_NOP;
- current+=3;
- goto modif_code;
- }
- /*}}} */
- break;
- case M_CALL:
- case M_JMP:
- case M_JMP_TRUE:
- case M_JMP_FALSE:
- if
- /*{{{ jmp arg in fixed range*/
- ( current[1]<FIXED_COMMAND_RANGE
- && current[1]>=-FIXED_COMMAND_RANGE-1
- )
- /*}}} */
- /*{{{ fixed argument version*/
- { current[0] = cur_token+RANGE_ADD+current[1]+1;
- current[1] = O_NOP;
- current+=2;
- goto modif_code;
- }
- /*}}} */
- break;
- default:
- break;
- }
- goto skip_code;
- /*}}} */
- case cut_strings:
- /*{{{ maybe shrink string*/
- { if (cur_token>O_NOP && cur_token<O_EXE_MACRO)
- /*{{{ handle prompt-strings*/
- { TOKEN *p_start;
-
- p_start=current+1;
- switch(cmd_type[*current-O_NOP])
- { case COM_IIP:
- /*{{{ skip arg*/
- p_start++;
- /*}}} */
- case COM_IP:
- /*{{{ skip arg*/
- p_start++;
- /*}}} */
- case COM_P:
- /*{{{ maybe define message*/
- { int lg;
- int x;
-
- /*{{{ get length of string*/
- for (lg=0;;p_start++)
- { if (*p_start<=0 || *p_start>=O_NOP)
- { if (lg>=STR_CUT_LG)
- break;
- lg=0;
- if
- ( *p_start==M_INT_STRING
- || *p_start==M_GET_HISTORY
- )
- p_start++;
- else if (*p_start==M_END_MACRO)
- break;
- }
- else
- lg++;
- }
- /*}}} */
- for (x=0;lg-x>=STR_CUT_LG;x++)
- { TOKEN new;
-
- if ((new=write_string(p_start-lg,lg-x,rc_string_gen)))
- { TOKEN *source;
- TOKEN *dest;
-
- *(p_start-1-x)= -new;
- /*{{{ shift*/
- for
- ( source=p_start-1-lg,dest=p_start-2-x
- ; source>=current
- ; source-=1,dest-=1
- )
- *dest= *source;
- /*}}} */
- /*{{{ fill with O_NOP*/
- for (lg-=x;--lg;)
- *current++=O_NOP;
- /*}}} */
- goto modif_code;
- }
- }
- }
- /*}}} */
- default:
- break;
- }
- }
- /*}}} */
- else if (cur_token<O_NOP && cur_token>0)
- /*{{{ handle text_string*/
- { TOKEN *str;
- int lg;
-
- for
- ( str=current+1,lg=1
- ; str!=end
- && *str>0
- && *str<O_NOP
- && !jumped_on(str,str+1)
- && lg<128
- ; str++,lg++
- );
- if (lg>=STR_CUT_LG+1)
- { TOKEN new;
-
- if ((new=write_string(current,lg,rc_string_gen)))
- { *current++=M_ASCII;
- *current++= -new;
- while (current!=str)
- *current++=O_NOP;
- goto modif_code;
- }
- }
- }
- /*}}} */
- goto default_opti;
- }
- /*}}} */
- default:
- default_opti:
- /*{{{ normal command optimization*/
- switch (cur_token)
- {
- /*{{{ M_CALL ...*/
- case M_CALL:
- dest=jmp_dest(current);
- if
- /*{{{ M_CALL x;M_END_MACRO -> M_JMP x; M_END_MACRO*/
- (next!=end && *next==M_END_MACRO)
- { *current=M_JMP;
- current=next;
- goto modif_code;
- }
- /*}}} */
- else if
- /*{{{ M_CALL x; .. x:M_END_MACRO -> O_NOP; O_NOP; ..*/
- ( dest!=end && *dest==M_END_MACRO )
- { *current++=O_NOP;
- *current++=O_NOP;
- goto modif_code;
- }
- /*}}} */
- goto skip_code;
- /*}}} */
- /*{{{ M_JMP ...*/
- case M_JMP:
- dest=jmp_dest(current);
- if
- /*{{{ M_JMP x; .. x:M_END_MACRO -> M_END_MACRO; O_NOP; ..*/
- ( dest!=end && *dest==M_END_MACRO)
- { *current++=M_END_MACRO;
- *current++=O_NOP;
- goto modif_code;
- }
- /*}}} */
- else if
- /*{{{ M_JMP x;x: -> O_NOP; O_NOP;*/
- (dest==next)
- { *current++=O_NOP;
- *current++=O_NOP;
- goto modif_code;
- }
- /*}}} */
- goto skip_code;
- /*}}} */
- /*{{{ M_JMP_? ...*/
- case M_JMP_FALSE:
- case M_JMP_TRUE:
- dest=jmp_dest(current);
- if
- /*{{{ M_JMP_COND x;x: -> O_NOP;O_NOP;*/
- (dest==next)
- { *current++=O_NOP;
- *current++=O_NOP;
- goto modif_code;
- }
- /*}}} */
- else if
- /*{{{ M_JMP_COND x;M_JMP_COND y; -> M_JMP_COND x;[O_NOP;O_NOP]|[M_JMP y]*/
- ( next!=end
- && (*next==M_JMP_FALSE || *next==M_JMP_TRUE)
- && !jumped_on(next,next+2)
- )
- { if (*next==cur_token)
- { current+=2;
- *current++=O_NOP;
- *current++=O_NOP;
- }
- else
- { current+=2;
- *current++=M_JMP;
- current++;
- }
- goto modif_code;
- }
- /*}}} */
- goto skip_code;
- /*}}} */
- /*{{{ M_END_MACRO ...*/
- case M_END_MACRO:
- if
- /*{{{ M_END M_END -> O_NOP M_END*/
- (next!=end && *next==M_END_MACRO)
- { *current++=O_NOP;
- goto modif_code;
- }
- /*}}} */
- goto skip_code;
- /*}}} */
- /*{{{ M_ADD_COUNTER ...*/
- case M_ADD_COUNTER:
- if
- /*{{{ ADD x 0 -> NOP NOP NOP*/
- ( *(current+2)==0 )
- { *current++=O_NOP;
- *current++=O_NOP;
- *current++=O_NOP;
- goto modif_code;
- }
- /*}}} */
- else if (next!=end && !jumped_on(next,next_command(next)))
- { if
- /*{{{ ADD x n ADD x m -> NOP NOP NOP ADD X n+m*/
- (*next==M_ADD_COUNTER && *(next+1)==*(current+1))
- { *(next+2)+=*(current+2);
- *current++=O_NOP;
- *current++=O_NOP;
- *current++=O_NOP;
- goto modif_code;
- }
- /*}}} */
- }
- goto skip_code;
- /*}}} */
- /*{{{ some complex statements sequences*/
- default:
- if (next!=end)
- { TOKEN *n_next;
-
- n_next=next_command(next);
- if (!jumped_on(next,n_next))
- switch (cur_token)
- {
- /*{{{ M_PUSH_INT ...*/
- case M_PUSH_INT:
- if (*next==M_POP_INT)
- if
- /*{{{ PUSH x POP x -> NOP*/
- (*(next+1)==*(current+1))
- { *current++=O_NOP;
- *current++=O_NOP;
- *current++=O_NOP;
- *current++=O_NOP;
- goto modif_code;
- }
- /*}}} */
- else if
- /*{{{ PUSH y POP x ADD x n -> SET x n SUM x y*/
- ( next+2!=end
- && *(next+2)==M_ADD_COUNTER
- && *(next+3)==*(next+1)
- && !(jumped_on(next+2,next+4))
- )
- { int n= *(next+4);
- int x= *(next+1);
- int y= *(current+1);
-
- *current++=O_NOP;
- *current++=M_SET_COUNTER;
- *current++=(TOKEN)x;
- *current++=(TOKEN)n;
- *current++=M_SUM_COUNTER;
- *current++=(TOKEN)x;
- *current++=(TOKEN)y;
- goto modif_code;
- }
- /*}}} */
- else if
- /*{{{ PUSH x POP y INV y SUM y z INV y -> PUSH z POP y INV y SUM y x NOP NOP*/
- ( (current+11)<end
- && !jumped_on(current,current+11)
- && *(next+2)==M_INV_COUNTER
- && *(next+4)==M_SUM_COUNTER
- && *(next+7)==M_INV_COUNTER
- && *(next+1)==*(next+3)
- && *(next+1)==*(next+5)
- && *(next+1)==*(next+8)
- )
- { int x=*(current+1);
- int y=*(next+1);
- int z=*(next+6);
-
- *current++=M_PUSH_INT;
- *current++=(TOKEN)z;
- *current++=M_POP_INT;
- *current++=(TOKEN)y;
- *current++=M_INV_COUNTER;
- *current++=(TOKEN)y;
- *current++=M_SUM_COUNTER;
- *current++=(TOKEN)y;
- *current++=(TOKEN)x;
- *current++=O_NOP;
- *current++=O_NOP;
- goto modif_code;
- }
- /*}}} */
- else if
- /*{{{ PUSH x POP dummy TEST dummy -> NOP NOP NOP NOP TEST x*/
- ( isdummy(*(next+1))
- && next+2!=end
- && (*(next+2)==M_NULL_COUNTER || *(next+2)==M_POSITIV_COUNTER)
- && !jumped_on(next+2,next+4)
- && *(next+3)==*(next+1)
- )
- { *(next+3)=*(current+1);
- *current++=O_NOP;
- *current++=O_NOP;
- *current++=O_NOP;
- *current++=O_NOP;
- goto modif_code;
- }
- /*}}} */
- else if
- /*{{{ PUSH x POP dummy SUM y dummy -> NOP NOP NOP NOP SUM y x*/
- ( isdummy(*(next+1))
- && next+2!=end
- && *(next+2)==M_SUM_COUNTER
- && !jumped_on(next+2,next+5)
- && *(next+4)==*(next+1)
- )
- { *(next+4)=*(current+1);
- *current++=O_NOP;
- *current++=O_NOP;
- *current++=O_NOP;
- *current++=O_NOP;
- goto modif_code;
- }
- /*}}} */
- goto skip_code;
- /*}}} */
- /*{{{ M_INV ...*/
- case M_INV_COUNTER:
- if
- /*{{{ INV x INV x -> NOP NOP NOP NOP*/
- (*next==M_INV_COUNTER && *(current+1)==*(next+1))
- { *current++=O_NOP;
- *current++=O_NOP;
- *current++=O_NOP;
- *current++=O_NOP;
- goto modif_code;
- }
- /*}}} */
- else if
- /*{{{ INV x ADD x n -> ADD x -n INV x*/
- ( *next==M_ADD_COUNTER && *(current+1)==*(next+1))
- { int x= *(current+1);
- int n= -*(next+2);
-
- *current++=M_ADD_COUNTER;
- *current++=x;
- *current++=n;
- *current=M_INV_COUNTER;
- *(current+1)=x;
- goto modif_code;
- }
- /*}}} */
- else if
- /*{{{ INV dummy NULL_COUNTER dummy -> NOP NOP NULL_COUNTER dummy*/
- ( next[0]==M_NULL_COUNTER
- && next[1]==current[1]
- && isdummy(current[1])
- )
- { *current++=O_NOP;
- *current=O_NOP;
- current=n_next;
- goto modif_code;
- }
- /*}}} */
- goto skip_code;
- /*}}} */
- /*{{{ M_SUM_COUNTER ...*/
- case M_SUM_COUNTER:
- if
- /*{{{ SUM x y ADD x n -> ADD x n SUM x y*/
- ( *next==M_ADD_COUNTER
- && *(current+1)==*(next+1)
- && *(current+1)!=*(current+2)
- )
- { int n= *(next+2);
- int y= *(current+2);
-
- *current++=M_ADD_COUNTER;
- current++;
- *current++=n;
- *current++=M_SUM_COUNTER;
- current++;
- *current++=y;
- goto modif_code;
- }
- /*}}} */
- goto skip_code;
- /*}}} */
- /*{{{ M_ECHO_P ...*/
- case M_ECHO_P:
- if (*next==M_ECHO_P && (n_next-current)<32)
- { TOKEN *s,*d;
-
- for (s=next-2,d=next;s>=current;*d--= *s--);
- *current++=O_NOP;
- *current++=O_NOP;
- goto modif_code;
- }
- goto skip_code;
- /*}}} */
- /*{{{ M_SET_COUNTER ...*/
- case M_SET_COUNTER:
- { TOKEN *dest1=current+1;
- TOKEN *dest2=next+1;
- TOKEN *arg1=current+2;
- TOKEN *arg2=next+2;
-
- if
- /*{{{ SET x n;INV x -> SET x -n; NOP NOP*/
- (*next==M_INV_COUNTER && *dest2==*dest1)
- { *arg1= -*arg1;
- *next++=O_NOP;
- *next++=O_NOP;
- current=next;
- goto modif_code;
- }
- /*}}} */
- else if
- /*{{{ SET x n; SET x m; -> NOP NOP NOP SET x m*/
- (*next==M_SET_COUNTER && *dest2==*dest1)
- { *current++=O_NOP;
- *current++=O_NOP;
- *current++=O_NOP;
- goto modif_code;
- }
- /*}}} */
- else if
- /*{{{ SET x n; SUM y x; -> SET x n; ADD y n | NOP NOP NOP ADD y n*/
- (*next==M_SUM_COUNTER && *arg2==*dest1)
- { *next=M_ADD_COUNTER;
- *arg2= *arg1;
- if (isdummy(*dest1))
- { *current++=O_NOP;
- *current++=O_NOP;
- *current++=O_NOP;
- }
- else
- { current+=3;
- }
- goto modif_code;
- }
- /*}}} */
- else if
- /*{{{ SET x 0; SUM x y; -> PUSH y POP x NOP NOP*/
- ( *next==M_SUM_COUNTER && *dest2==*dest1 && *arg1==0)
- { int s=*arg2;
- int d=*dest1;
-
- *current++=M_PUSH_INT;
- *current++=(TOKEN)s;
- *current++=M_POP_INT;
- *current++=(TOKEN)d;
- *current++=O_NOP;
- *current++=O_NOP;
- goto modif_code;
- }
- /*}}} */
- else if
- /*{{{ SET x n; ADD x m; -> NOP NOP NOP SET x n+m*/
- (*next==M_ADD_COUNTER && *dest2==*dest1)
- { *arg2+=*arg1;
- *current++=O_NOP;
- *current++=O_NOP;
- *current++=O_NOP;
- *current=M_SET_COUNTER;
- goto modif_code;
- }
- /*}}} */
- else if
- /*{{{ SET x n ASCII x -> SET X n ; n; | NOP NOP NOP n*/
- (*next==M_ASCII && *dest2==*dest1 && next_command(dest1)==next)
- { *next++ = *arg1;
- *next++ = O_NOP;
- if (isdummy(*dest1))
- { *current++=O_NOP;
- *current++=O_NOP;
- *current=O_NOP;
- }
- current=next;
- goto modif_code;
- }
- /*}}} */
- else if
- /*{{{ SET x n TEST x JMP_cond d -> SET x n NOP NOP JMP d*/
- ( ( *next==M_NULL_COUNTER
- || *next==M_POSITIV_COUNTER
- )
- && *(next+1)==*(current+1)
- && (next+2)!=end
- && ( *(next+2)==M_JMP_TRUE
- || *(next+2)==M_JMP_FALSE
- )
- && !jumped_on(next+2,next+4)
- )
- { boolean jmp;
-
- jmp=(*next==M_POSITIV_COUNTER)?(*(current+2)>0):(*(current+2)==0);
- if (isdummy(*(current+1)))
- /*{{{ set dummy not needed*/
- { *current++=O_NOP;*current++=O_NOP;*current++=O_NOP; }
- /*}}} */
- /*{{{ test not needed*/
- *next++=O_NOP;*next++=O_NOP;
- /*}}} */
- if (*next!=M_JMP_TRUE) jmp = !jmp;
- if (jmp)
- /*{{{ jmp_cond -> jmp*/
- { *next=M_JMP;
- next+=2;
- }
- /*}}} */
- else
- /*{{{ jmp not needed*/
- { *next++=O_NOP;
- *next++=O_NOP;
- }
- /*}}} */
- current=next;
- goto modif_code;
- }
- /*}}} */
- else if
- /*{{{ SET x n TEST_CHARxxx dummy -> [SET x n;] TEST_CHARxxx n*/
- ( *(next+1)==*(current+1)
- && (*next==M_TEST_CC || *next==M_TEST_H_CC || *next==M_TEST_L_CC)
- )
- { switch (*next)
- { case M_TEST_H_CC: *next=M_TEST_CHAR_HIGH;break;
- case M_TEST_L_CC: *next=M_TEST_CHAR_LOW; break;
- default: *next=M_TEST_CHAR; break;
- }
- *(next+1)=*(current+2);
- if (isdummy(*(current+1)))
- { *current++=O_NOP;*current++=O_NOP;*current++=O_NOP; }
- else
- current=next;
- goto modif_code;
- }
- /*}}} */
- else if
- /*{{{ SET dummy n PUSH dummy POP x -> SET x n NOP NOP NOP NOP*/
- ( isdummy(*dest1)
- && *next==M_PUSH_INT
- && *dest1==*dest2
- && (next+2)!=end
- && *(next+2)==M_POP_INT
- && !jumped_on(next+2,next+4)
- )
- { *dest1= *(next+3);
- *next++=O_NOP;
- *next++=O_NOP;
- *next++=O_NOP;
- *next++=O_NOP;
- current=next;
- goto modif_code;
- }
- /*}}} */
- else if
- /*{{{ SET dummy n M_ECHO_I dummy -> M_ECHO_P n&255 M_END_MACRO O_NOP*/
- ( isdummy(*dest1)
- && *next==M_ECHO_I
- && *dest1==*dest2
- )
- { *current++=M_ECHO_P;
- *current++=(*arg1)&(O_NOP-1);
- *current++=M_END_MACRO;
- *current++=O_NOP;
- *current++=O_NOP;
- goto modif_code;
- }
- /*}}} */
- else if
- /*{{{ SET dummy n M_LOAD_MAC x dummy -> M_LOAD_MAC x -n*/
- ( isdummy(*dest1)
- && *next==M_LOAD_MAC
- && *arg2==*dest1
- )
- { int n;
-
- n= *arg1;
- *current++=M_LOAD_MAC;
- *current++= *dest2;
- *current++= -n;
- *current++=O_NOP;
- *current++=O_NOP;
- *current++=O_NOP;
- goto modif_code;
- }
- /*}}} */
- goto skip_code;
- }
- /*}}} */
- default:
- goto skip_code;
- }
- }
- /*}}} */
- skip_code:
- /*{{{ set current to next and loop*/
- current=next;
- continue;
- /*}}} */
- modif_code:
- /*{{{ count modifications and loop*/
- changed=True;
- modified++;
- continue;
- /*}}} */
- }
- /*}}} */
- }
- }
- /*}}} */
- }
- /*}}} */
- if (verbose_level>1)
- /*{{{ maybe print current optimization strip*/
- { s_jmp_cut+=jmp_cut;
- s_modified+=modified;
- s_shrink+=shrink;
- loop++;
- if (jmp_cut+modified+shrink && verbose_level>2)
- fprintf(stderr,F_OPT_FORMAT,loop,jmp_cut,modified,shrink);
- }
- /*}}} */
- if (!changed)
- { opt_type++;
- if (opt_type==set_fixed_cmd && !fix_args)
- opt_type++;
- if (opt_type!=opt_ready)
- changed=True;
- }
- }
- /*}}} */
- while (changed && loop_max-->0);
- /*{{{ check correct usage of arguments*/
- { TOKEN *current;
-
- for (current=start;current!=end;)
- { switch (*current)
- { TOKEN x;
-
- /*{{{ M_TEST_CHARxxx check char!*/
- case M_TEST_CHAR:
- case M_TEST_CHAR_LOW:
- case M_TEST_CHAR_HIGH:
- x= *(current+1);
- current+=2;
- if (x<0 || x>=O_NOP)
- goto warn_char;
- break;
- /*}}} */
- /*{{{ O_LANGUAGE check char!*/
- case O_LANGUAGE:
- current+=1;
- if (current!=end)
- { x= *current;
- if (x>=0 && x<O_NOP)
- { char **s;
-
- for (s=f_c_name,x=toupper(x);;s++)
- if (**s==x)
- break;
- else if (!**s)
- warn_char:{ error_po();
- fprintf
- ( stderr,
- F_WARN_CHAR,
- x,
- (100*(current-start))/(end-start)
- );
- break;
- }
- }
- }
- break;
- /*}}} */
- default:
- current=next_command(current);
- break;
- }
- }
-
- }
- /*}}} */
- if (verbose_level>1)
- /*{{{ maybe print current optimization strip*/
- if ((verbose_level==2 || loop>1) && s_jmp_cut+s_modified+s_shrink)
- fprintf(stderr,F_OPT_S_FORMAT,loop-1,s_jmp_cut,s_modified,s_shrink);
- /*}}} */
- return(end);
- }
- /*}}} */
- #endif
-